package com.unresyst;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.List;
import java.io.IOException;

import org.apache.commons.cli2.OptionException; 
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.neighborhood.ThresholdUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.CachingRecommender;
import org.apache.mahout.cf.taste.impl.recommender.GenericBooleanPrefItemBasedRecommender;
import org.apache.mahout.cf.taste.impl.recommender.GenericBooleanPrefUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.recommender.slopeone.SlopeOneRecommender;
import org.apache.mahout.cf.taste.impl.similarity.LogLikelihoodSimilarity;
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
import org.apache.mahout.cf.taste.impl.similarity.TanimotoCoefficientSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;

public class UnresystBoolRecommend {
    
    public static void main(String... args) throws FileNotFoundException, TasteException, IOException, OptionException {
        
        // create data source (model) - from the csv file            
        File ratingsFile = new File("datasets/train.txt"); 
        System.out.println("Read Training Set");
        DataModel model = new FileDataModel(ratingsFile);
        System.out.println("Generated Model");
        
        // create a simple SlopeOne recommender on our data
//        CachingRecommender cachingRecommender = new CachingRecommender(new SlopeOneRecommender(model));
        
        //create user similarity model
//        UserSimilarity userSimilarity = new PearsonCorrelationSimilarity(model);
//        UserNeighborhood neighborhood = new NearestNUserNeighborhood(3, userSimilarity, model);
//        Recommender recommender = new GenericUserBasedRecommender(model, neighborhood, userSimilarity);
//        Recommender cachingRecommender = new CachingRecommender(recommender);
        
        //create boolean pref model
//        ItemSimilarity similarity = new LogLikelihoodSimilarity(model);
//        Recommender recommender = new GenericBooleanPrefItemBasedRecommender(model, similarity);
//        Recommender cachingRecommender = new CachingRecommender(recommender);
//        System.out.println("Generated Recommender");
//        
        Long userid = null;
		Long itemid = null;
		Integer actualValue = null;
		double prefScore = 0;

		File file = new File("datasets/validate.txt");
//		BufferedReader reader = new BufferedReader(new FileReader(file));
//		
//		FileWriter writer = new FileWriter("datasets/LogLikelyhoodoutput.txt");		
//		String s = null;
//		do {
//			s = reader.readLine();
//			if (s == null)
//				break;
//			s = s.trim();
//			String[] parts = s.split(",");
//			userid = Long.parseLong(parts[0]);
//			itemid = Long.parseLong(parts[1]);
//			actualValue = Integer.parseInt(parts[2]);
//			prefScore = cachingRecommender.estimatePreference(userid, itemid);
//			String ss = userid + " " + itemid + " " + actualValue + " "
//					+ prefScore;
//			writer.write(ss);
//			writer.append('\n');
//			//System.out.print(prefScore+" ");
//		} while (s != null);
//		reader.close();
//		writer.close();
//		System.out.println("Done");
//		System.out.println("Generated Log Likelyhood output");
//		recommender=null;
//		cachingRecommender=null;
//		similarity=null;
//		reader=null;
//		
//		double thresholdValue=0.7;
//		UserSimilarity userSimilarity = new TanimotoCoefficientSimilarity(model);
//		UserNeighborhood neighborhood =new ThresholdUserNeighborhood(thresholdValue, userSimilarity, model);
//		recommender =new GenericBooleanPrefUserBasedRecommender(model, neighborhood, userSimilarity);
//		cachingRecommender = new CachingRecommender(recommender);
//        System.out.println("Generated Recommender");
//		
//        reader = new BufferedReader(new FileReader(file));
//        writer = new FileWriter("datasets/TanimotoCoefficientoutput.txt");		
//		s = null;
//		do {
//			s = reader.readLine();
//			if (s == null)
//				break;
//			s = s.trim();
//			String[] parts = s.split(",");
//			userid = Long.parseLong(parts[0]);
//			itemid = Long.parseLong(parts[1]);
//			actualValue = Integer.parseInt(parts[2]);
//			prefScore = cachingRecommender.estimatePreference(userid, itemid);
//			String ss = userid + " " + itemid + " " + actualValue + " "
//					+ prefScore;
//			writer.write(ss);
//			writer.append('\n');
//			//System.out.print(prefScore+" ");
//		} while (s != null);
//		reader.close();
//		writer.close();
//		System.out.println("Done");
//		System.out.println("Generated TanimotoCoefficient output");
//		recommender=null;
//		cachingRecommender=null;
//		neighborhood=null;
//		userSimilarity=null;
		
		UserSimilarity userSimilarity=new PearsonCorrelationSimilarity(model);
		UserNeighborhood userNeighborhood=new NearestNUserNeighborhood(3, userSimilarity, model);
		Recommender recommender =new GenericBooleanPrefUserBasedRecommender(model, userNeighborhood, userSimilarity);
		CachingRecommender cachingRecommender = new CachingRecommender(recommender);
        System.out.println("Generated Recommender");
		
        BufferedReader reader = new BufferedReader(new FileReader(file));
        FileWriter writer = new FileWriter("datasets/PearsonNeighborhoodUserBasedoutput.txt");		
		String s = null;
		do {
			s = reader.readLine();
			if (s == null)
				break;
			s = s.trim();
			String[] parts = s.split(",");
			userid = Long.parseLong(parts[0]);
			itemid = Long.parseLong(parts[1]);
			actualValue = Integer.parseInt(parts[2]);
			prefScore = cachingRecommender.estimatePreference(userid, itemid);
			String ss = userid + " " + itemid + " " + actualValue + " "
					+ prefScore;
			writer.write(ss);
			writer.append('\n');
			//System.out.print(prefScore+" ");
		} while (s != null);
		reader.close();
		writer.close();
		System.out.println("Done");
		System.out.println("Generated output");
		recommender=null;
		cachingRecommender=null;
		userNeighborhood=null;
		userSimilarity=null;
		

//        // for all users
//        for (LongPrimitiveIterator it = model.getUserIDs(); it.hasNext();){
//            long userId = it.nextLong();
//            
//            // get the recommendations for the user
//            List<RecommendedItem> recommendations = cachingRecommender.recommend(userId, 10);
//            
//            // if empty write something
//            if (recommendations.size() == 0){
//                System.out.print("User ");
//                System.out.print(userId);
//                System.out.println(": no recommendations");
//            }
//                            
//            // print the list of recommendations for each 
//            for (RecommendedItem recommendedItem : recommendations) {
//                System.out.print("User ");
//                System.out.print(userId);
//                System.out.print(": ");
//                System.out.println(recommendedItem);
//            }	
//            break;
//        }	// for all users        
    }	//main
}	//class